package com.green.common.util;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.swetake.util.Qrcode;

public class ImageUtil {
	/**
	 * 给图片加水印
	 * @param workmarkImage 要加的水印图片
	 * @param x 水印位置X
	 * @param y 水印位置Y
	 * @return 加水印后的图片
	 */
    public static byte[] watermarkImage(byte[] workmarkImage, byte[] targetImage, int x, int y) {
        try {
            Image src = ImageIO.read(new ByteArrayInputStream(targetImage));
            int wideth = src.getWidth(null);
            int height = src.getHeight(null);
            BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.createGraphics();
            g.drawImage(src, 0, 0, wideth, height, null);

            // 水印文件
            Image src_biao = ImageIO.read(new ByteArrayInputStream(workmarkImage));
            int wideth_biao = src_biao.getWidth(null);
            int height_biao = src_biao.getHeight(null);
            g.drawImage(src_biao, wideth - wideth_biao - x, height - height_biao - y, wideth_biao, height_biao, null);
            // /
            g.dispose();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            encoder.encode(image);
            out.close();
            return out.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return null;
    }
    
    /**
     * 压缩图片（采用JDK压缩）
     * @param image 要压缩的图片
     * @param width 压缩后的宽
     * @param height 压缩后的高
     * @param quality 质量
     * @return
     */
    public static byte[] compressImage(byte[] image, Integer width, Integer height, float quality) {
    	if(width == null || height == null) return image;
        Image src;
        try {
            src = javax.imageio.ImageIO.read(new ByteArrayInputStream(image)); // 构造Image对象
            int old_w = src.getWidth(null); // 得到源图宽
            int old_h = src.getHeight(null);
            int new_w = 0;
            int new_h = 0; // 得到源图长

            // 图片跟据长宽留白，成一个正方形图。
            BufferedImage oldpic;
            if (old_w > old_h) {
                oldpic = new BufferedImage(old_w, old_w, BufferedImage.TYPE_INT_RGB);
            } else {
                if (old_w < old_h) {
                    oldpic = new BufferedImage(old_h, old_h, BufferedImage.TYPE_INT_RGB);
                } else {
                    oldpic = new BufferedImage(old_w, old_h, BufferedImage.TYPE_INT_RGB);
                }
            }
            Graphics2D g = oldpic.createGraphics();
            g.setColor(Color.white);
            if (old_w > old_h) {
                g.fillRect(0, 0, old_w, old_w);
                g.drawImage(src, 0, (old_w - old_h) / 2, old_w, old_h, Color.white, null);
            } else {
                if (old_w < old_h) {
                    g.fillRect(0, 0, old_h, old_h);
                    g.drawImage(src, (old_h - old_w) / 2, 0, old_w, old_h, Color.white, null);
                } else {
                    // g.fillRect(0,0,old_h,old_h);
                    g.drawImage(src.getScaledInstance(old_w, old_h, Image.SCALE_SMOOTH), 0, 0, null);
                }
            }
            g.dispose();
            src = oldpic;
            // 图片调整为方形结束
            if (old_w > width)
                new_w = width;
            else
                new_w = old_w;
            if (old_h > height)
                new_h = height;// 计算新图长宽
            else
                new_h = old_h;
            BufferedImage tag = new BufferedImage(new_w, new_h, BufferedImage.TYPE_INT_RGB);
            // tag.getGraphics().drawImage(src,0,0,new_w,new_h,null); //绘制缩小后的图
            tag.getGraphics().drawImage(src.getScaledInstance(new_w, new_h, Image.SCALE_SMOOTH), 0, 0, null);
            ByteArrayOutputStream newimage = new ByteArrayOutputStream(); // 输出到文件流
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);
            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);

            jep.setQuality(quality, true);
            encoder.encode(tag, jep);
            // encoder.encode(tag); //近JPEG编码
            newimage.close();
            return newimage.toByteArray();
        } catch (IOException ex) {
            ex.getStackTrace();
        }
        return null;
    }
    
	public static byte[] imageToBytes(BufferedImage image,String formatName){
    	final ByteArrayOutputStream out=new ByteArrayOutputStream();
    	try {
			ImageIO.write(image, formatName, out);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				out.close();
			} catch (IOException e) {
			}
		}
        
		return out.toByteArray();
    }
	
	
	 /** 
     * 生成二维码(QRCode)图片的公共方法 
     * @param content 存储内容 
     * @param imgType 图片类型 
     * @param size 二维码尺寸 
     * @return 
     */  
    public static  BufferedImage qRCodeCommon(String content, String imgType, int size) {  
        BufferedImage bufImg = null;  
        try {  
        Qrcode qrcodeHandler = new Qrcode();  
            // 设置二维码排错率，可选L(7%)、M(15%)、Q(25%)、H(30%)，排错率越高可存储的信息越少，但对二维码清晰度的要求越小   
            qrcodeHandler.setQrcodeErrorCorrect('M');  
            qrcodeHandler.setQrcodeEncodeMode('B');  
            // 设置设置二维码尺寸，取值范围1-40，值越大尺寸越大，可存储的信息越大   
            qrcodeHandler.setQrcodeVersion(size);  
            // 获得内容的字节数组，设置编码格式   
            byte[] contentBytes = content.getBytes("utf-8");  
            // 图片尺寸   
            int imgSize = 67 + 12 * (size - 1);  
            bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);  
            Graphics2D gs = bufImg.createGraphics();  
            // 设置背景颜色   
            gs.setBackground(Color.WHITE);  
            gs.clearRect(0, 0, imgSize, imgSize);  
  
            // 设定图像颜色> BLACK   
            gs.setColor(Color.BLACK);  
            // 设置偏移量，不设置可能导致解析出错   
            int pixoff = 2;  
            // 输出内容> 二维码   
            if (contentBytes.length > 0 && contentBytes.length < 800) {  
                boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);  
                for (int i = 0; i < codeOut.length; i++) {  
                    for (int j = 0; j < codeOut.length; j++) {  
                        if (codeOut[j][i]) {  
                            gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);  
                        }  
                    }  
                }  
            } else {  
                throw new Exception("QRCode content bytes length = " + contentBytes.length + " not in [0, 800].");  
            }  
            gs.dispose();  
            bufImg.flush();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return bufImg;  
    } 
    /**
     * 网络截图
     * @param src
     * @param x
     * @param y
     * @param width
     * @param height
     * @return
     * @throws IOException 
     */
    public static byte[] cutNetImage(String src, int x, int y, int width, int height) {
        ByteArrayOutputStream baos = null;
        byte[] bytes = null;
        try {
            Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("jpg");
            InputStream in = readNetImg(src);
            baos = cutImage(x, y, width, height, readers, in);
            bytes = baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(baos!=null){
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bytes;
    }
    /**
     * 截取本地图片
     * @param src
     * @param x
     * @param y
     * @param width
     * @param height
     * @return
     */
    public static byte[] cuteNativeImage(String src, int x, int y, int width, int height){
        ByteArrayOutputStream baos = null;
        byte[] bytes = null;
        try {
            Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("jpg");
            InputStream in = new FileInputStream(src);
            baos = cutImage(x, y, width, height, readers, in);
            bytes = baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(baos!=null){
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bytes;
    }
    
    public static byte[] compressImage(byte[] image, Integer width, Integer height){
        if(width == null || height == null) return image;
        Image src;
        try {
            src = javax.imageio.ImageIO.read(new ByteArrayInputStream(image)); // 构造Image对象
//            int old_w = src.getWidth(null); // 得到源图宽
//            int old_h = src.getHeight(null);
         // 为等比缩放计算输出的图片宽度及高度
//            double rate1 = ((double) old_w) / (double) width ;
//            double rate2 = ((double) old_h) / (double) height;
//            double rate = rate1 > rate2 ? rate1 : rate2;
//            w_hint new_w = (int) (((double) old_w) / rate);
//            int ne = (int) (((double) old_h) / rate);
            /** 宽,高设定 */
            BufferedImage tag = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
            tag.getGraphics().drawImage(src, 0, 0, width, height, null);
            ByteArrayOutputStream newimage = new ByteArrayOutputStream(); // 输出到文件流
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);
            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);

            jep.setQuality(1.0f, true);
            encoder.encode(tag, jep);
            // encoder.encode(tag); //近JPEG编码
            newimage.close();
            return newimage.toByteArray();
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 截取图片
     * @param x
     * @param y
     * @param width
     * @param height
     * @param readers
     * @param in
     * @return
     * @throws IOException
     */
    private static ByteArrayOutputStream cutImage(int x, int y, int width, int height, Iterator<ImageReader> readers, InputStream in) throws IOException {
        ImageInputStream imgInput = ImageIO.createImageInputStream(in);
        ImageReader reader = (ImageReader) readers.next();
        reader.setInput(imgInput, true);
        ImageReadParam param = reader.getDefaultReadParam();
        Rectangle rectangle = new Rectangle(x, y, width, height);
        param.setSourceRegion(rectangle);
        BufferedImage bimg = reader.read(0, param);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(bimg, "jpg", baos);
        return baos;
    }
    /**
     * 获取网络图片字节流
     * @param httpurl
     * @return
     */
    private static InputStream readNetImg(String httpurl) {
        InputStream in = null;
        try {
            URL url = new URL(httpurl);
            in = new BufferedInputStream(url.openStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return in;
    }
    /**
     * 读取远程图片
     * @param httpUrl
     * @return
     */
    public static ImageReader netImage(String httpUrl){
        try {
            Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("jpg");
            InputStream in = readNetImg(httpUrl);
            ImageInputStream imgInput = ImageIO.createImageInputStream(in);
            ImageReader reader = (ImageReader) readers.next();
            reader.setInput(imgInput);
            return reader;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
